package com.chatai.service;

import com.chatai.config.JwtUtils;
import com.chatai.dto.UserLoginDTO;
import com.chatai.dto.UserRegisterDTO;
import com.chatai.model.User;
import com.chatai.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Service
public class AuthService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    // 系统启动时自动创建管理员用户
    @EventListener(ApplicationReadyEvent.class)
    public void createAdminUser() {
        // 检查是否已存在管理员用户
        User adminUser = userRepository.findByUsername("3140015798").orElse(null);
        if (adminUser == null) {
            // 创建管理员用户
            adminUser = new User();
            adminUser.setUsername("3140015798");
            adminUser.setPassword(passwordEncoder.encode("dog1128620"));
            adminUser.setEmail("admin@example.com");
            adminUser.setAvatar("https://avatars.githubusercontent.com/u/10000?v=4");
            adminUser.setRole("ADMIN");
            adminUser.setCreatedAt(LocalDateTime.now());
            userRepository.save(adminUser);
            System.out.println("管理员用户已创建：3140015798");
        }
    }
    
    // 用户注册
    public Map<String, Object> register(UserRegisterDTO registerDTO) {
        System.out.println("======================= 注册请求开始 =======================");
        try {
            // 添加详细日志输出
            System.out.println("开始处理注册请求: username=" + registerDTO.getUsername());
            
            // 验证密码和确认密码是否一致
            if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
                System.out.println("密码和确认密码不一致");
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "密码和确认密码不一致");
                errorResponse.put("error", "passwords_do_not_match");
                errorResponse.put("success", false);
                return errorResponse;
            }
            
            // 检查用户名是否已存在
            boolean usernameExists = userRepository.existsByUsername(registerDTO.getUsername());
            System.out.println("检查用户名是否存在: " + usernameExists);
            if (usernameExists) {
                System.out.println("用户名已存在: " + registerDTO.getUsername());
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "用户名已存在");
                errorResponse.put("error", "username_already_exists");
                errorResponse.put("success", false);
                return errorResponse;
            }
            
            // 检查邮箱是否已存在
            boolean emailExists = userRepository.existsByEmail(registerDTO.getEmail());
            System.out.println("检查邮箱是否存在: " + emailExists);
            if (emailExists) {
                System.out.println("邮箱已被注册: " + registerDTO.getEmail());
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "邮箱已被注册");
                errorResponse.put("error", "email_already_exists");
                errorResponse.put("success", false);
                return errorResponse;
            }
            
            // 创建新用户
            User user = new User();
            user.setUsername(registerDTO.getUsername());
            user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
            user.setEmail(registerDTO.getEmail()); // 使用用户提供的邮箱
            user.setAvatar(registerDTO.getAvatar());
            user.setCreatedAt(LocalDateTime.now());
            user.setLastLogin(null);
            user.setRole("USER"); // 默认角色为普通用户
            
            System.out.println("准备保存用户到数据库，用户对象: " + user);
            User savedUser = userRepository.save(user);
            System.out.println("用户保存成功，ID: " + savedUser.getId());
            
            // 生成Token
            System.out.println("为用户生成JWT Token");
            Map<String, Object> claims = new HashMap<>();
            claims.put("role", savedUser.getRole());
            String token = jwtUtils.generateToken(savedUser.getUsername(), claims);
            
            Map<String, Object> response = new HashMap<>();
            response.put("token", token);
            response.put("username", savedUser.getUsername());
            response.put("userId", savedUser.getId());
            response.put("role", savedUser.getRole());
            response.put("success", true);
            
            System.out.println("注册成功完成");
            System.out.println("======================= 注册请求结束(成功) =======================");
            return response;
        } catch (Exception e) {
            System.out.println("======================= 注册请求结束(失败) =======================");
            System.out.println("注册过程中发生异常: " + e.getMessage());
            System.out.println("异常类型: " + e.getClass().getName());
            System.out.println("异常堆栈:");
            e.printStackTrace(); // 打印完整的异常堆栈
            
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("message", "注册过程中发生错误: " + e.getMessage());
            errorResponse.put("error", "registration_failed");
            errorResponse.put("success", false);
            errorResponse.put("exception_type", e.getClass().getName());
            return errorResponse;
        }
    }
    
    // 用户登录 - 修复身份认证逻辑，添加更详细的错误处理
    public Map<String, Object> login(UserLoginDTO loginDTO) {
        System.out.println("[AuthService] 收到登录请求，开始处理...");
        try {
            System.out.println("[AuthService] LoginDTO对象: " + loginDTO);
            
            if (loginDTO == null) {
                System.out.println("[AuthService] 错误: loginDTO为null");
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "请求参数为空");
                errorResponse.put("error", "empty_request");
                errorResponse.put("success", false);
                return errorResponse;
            }
            
            String username = loginDTO.getUsername();
            String password = loginDTO.getPassword();
            
            System.out.println("[AuthService] 登录凭证: username=" + username + ", password长度=" + (password != null ? password.length() : "null"));
            
            // 恢复用户查找逻辑
            System.out.println("[AuthService] 开始查找用户...");
            User user = null;
            try {
                if (isValidEmail(username)) {
                    System.out.println("[AuthService] 按邮箱查找: " + username);
                    user = userRepository.findByEmail(username).orElse(null);
                } else {
                    System.out.println("[AuthService] 按用户名查找: " + username);
                    user = userRepository.findByUsername(username).orElse(null);
                }
                
                System.out.println("[AuthService] 用户查找结果: " + (user != null ? "找到用户: " + user.getUsername() : "未找到用户"));
                
                if (user == null) {
                    System.out.println("[AuthService] 用户不存在: " + username);
                    Map<String, Object> errorResponse = new HashMap<>();
                    errorResponse.put("message", "用户名或密码错误");
                    errorResponse.put("error", "invalid_credentials");
                    errorResponse.put("success", false);
                    return errorResponse;
                }
            } catch (Exception e) {
                System.out.println("[AuthService] 用户查找异常: " + e.getMessage());
                e.printStackTrace();
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "系统错误，请稍后再试");
                errorResponse.put("error", "system_error");
                errorResponse.put("success", false);
                return errorResponse;
            }
            
            // 执行真正的身份认证
            System.out.println("[AuthService] 执行身份认证");
            try {
                // 使用AuthenticationManager进行认证
                Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
                );
                
                // 设置认证信息到安全上下文
                SecurityContextHolder.getContext().setAuthentication(authentication);
                
                // 生成有效的JWT Token
                Map<String, Object> claims = new HashMap<>();
                claims.put("role", user.getRole());
                claims.put("userId", user.getId());
                String token = jwtUtils.generateToken(username, claims);
                
                // 更新用户最后登录时间
                user.setLastLogin(LocalDateTime.now());
                userRepository.save(user);
                
                Map<String, Object> response = new HashMap<>();
                response.put("token", token);
                response.put("username", user.getUsername());
                response.put("userId", user.getId());
                response.put("avatar", user.getAvatar());
                response.put("email", user.getEmail());
                response.put("role", user.getRole());
                response.put("success", true);
                
                System.out.println("[AuthService] 登录成功，返回有效Token");
                return response;
            } catch (BadCredentialsException e) {
                System.out.println("[AuthService] 身份认证失败: 用户名或密码错误");
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "用户名或密码错误");
                errorResponse.put("error", "invalid_credentials");
                errorResponse.put("success", false);
                return errorResponse;
            } catch (Exception e) {
                System.out.println("[AuthService] 身份认证过程中发生异常: " + e.getMessage());
                e.printStackTrace();
                Map<String, Object> errorResponse = new HashMap<>();
                errorResponse.put("message", "登录过程中发生错误: " + e.getMessage());
                errorResponse.put("error", "authentication_failed");
                errorResponse.put("success", false);
                return errorResponse;
            }
        } catch (Exception e) {
            System.out.println("[AuthService] 登录过程中发生异常: " + e.getMessage());
            System.out.println("[AuthService] 异常类型: " + e.getClass().getName());
            e.printStackTrace();
            
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("message", "登录过程中发生错误: " + e.getMessage());
            errorResponse.put("error", "login_exception");
            errorResponse.put("success", false);
            return errorResponse;
        }
    }
    
    // 获取当前登录用户
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || "anonymousUser".equals(authentication.getName())) {
            // 当未认证或匿名用户时，返回默认测试用户
            return createOrGetDefaultUser();
        }
        
        String loginName = authentication.getName();
        User user;
        
        // 检查是邮箱还是用户名
        if (isValidEmail(loginName)) {
            user = userRepository.findByEmail(loginName)
                    .orElse(null);
        } else {
            user = userRepository.findByUsername(loginName)
                    .orElse(null);
        }
        
        // 如果找不到用户，返回默认测试用户
        if (user == null) {
            return createOrGetDefaultUser();
        }
        
        return user;
    }
    
    // 创建或获取默认测试用户
    private User createOrGetDefaultUser() {
        // 尝试查找默认用户
        Optional<User> optionalUser = userRepository.findByUsername("test_user");
        if (optionalUser.isPresent()) {
            return optionalUser.get();
        }
        
        // 创建默认用户
        User defaultUser = new User();
        defaultUser.setUsername("test_user");
        defaultUser.setEmail("test@example.com");
        defaultUser.setPassword(passwordEncoder.encode("password"));
        defaultUser.setCreatedAt(LocalDateTime.now());
        defaultUser.setRole("USER");
        return userRepository.save(defaultUser);
    }
    
    // 验证邮箱格式
    private boolean isValidEmail(String email) {
        if (email == null) {
            return false;
        }
        String emailRegex = "^[A-Za-z0-9+_.-]+@(.+)$";
        return email.matches(emailRegex);
    }
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 首先尝试通过用户名查找
        User user = userRepository.findByUsername(username)
                .orElseGet(() -> {
                    // 如果用户名不存在，尝试通过邮箱查找
                    if (isValidEmail(username)) {
                        return userRepository.findByEmail(username)
                                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
                    }
                    throw new UsernameNotFoundException("用户不存在: " + username);
                });
        
        // 创建并返回UserDetails对象，包含用户角色信息
        // 使用authorities方法而不是roles方法，避免自动添加ROLE_前缀
        return org.springframework.security.core.userdetails.User
                .withUsername(user.getUsername())
                .password(user.getPassword())
                .authorities(user.getRole()) // 直接使用用户角色作为权限
                .accountExpired(false)
                .accountLocked(false)
                .credentialsExpired(false)
                .disabled(false)
                .build();
    }
    
    // 用户退出登录 - 进一步简化实现，确保不会抛出异常
    public Map<String, Object> logout() {
        System.out.println("[AuthService] 执行退出登录操作...");
        Map<String, Object> response = new HashMap<>();
        // 简化实现，直接返回成功响应
        response.put("success", true);
        response.put("message", "退出登录成功");
        System.out.println("[AuthService] 退出登录请求处理成功");
        return response;
    }
}